/*
 * Copyright (C) 2010 Seapeak.Xu
 *
 * fostmq may be copied only under the terms of the GNU General
 * Public License V3, which may be found in the fostmq source kit.
 *
 * Created on: 2010-10-15
 * Author: Seapeak.Xu
 */

#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <errno.h>
#include <event.h>
#include <string.h>

#include "fost_thread.h"
#include "fost_logger.h"
#include "fost_notifypool.h"
#include "fost_sock.h"
#include "fost_typedef.h"
#include "fost_event.h"
#include "fost_notify.h"
#include "fost_taskpool.h"
#include "fost_mgnb.h"

int notify_event_init(notify_elt_t *notify_elt)
{
	if(NULL == notify_elt)
	{
		log_error("File:%s,Line:%d,Function:%s.the argument is null.",
				__FILE__,__LINE__,__FUNCTION__);
		return -1;
	}

	if (0 != set_nonblocking(notify_elt->pipe_fds[0]))
	{
		log_error("File:%s,Line:%d,Function:%s.set pipe to nonblocking is fail.",
				__FILE__,__LINE__,__FUNCTION__);
		return -1;
	}
	int result = 0;
	struct event ev_notify;
	do
	{
		event_set(&ev_notify,notify_elt->pipe_fds[0],EV_READ|EV_PERSIST,notify_elt->func,&(notify_elt->idx));
		if(0 != event_base_set(notify_elt->ev_base,&ev_notify))
		{
			result = -1;
			log_error("File:%s,Line:%d,Function:%s.set notify event is fail.Error:%d,Info:%s.",
					__FILE__,__LINE__,__FUNCTION__,errno,strerror(errno));
			break;
		}
		if(0 != event_add(&ev_notify,NULL))
		{
			result = -1;
			log_error("File:%s,Line:%d,Function:%s.add notify event is fail.Errno:%d,Info:%s.",
					__FILE__,__LINE__,__FUNCTION__,errno,strerror(errno));
			break;
		}
		while(g_loop)
		{
			event_base_loop(notify_elt->ev_base,0);
		}
	}while(false);
	return result;
}

void notify_read_event(int sock,short events,void *arg)
{
	int client_sock;
	int bytes;
	if(NULL == arg || 0 >*((int *) arg))
	{
		log_error("File:%s,Line:%d,Function:%s.the notify elt index is null or less 0");
		return;
	}
	int idx = *((int*) (arg));
	while(g_loop)//magic,please donot touch
	{
		if(0 > (bytes = read(sock,&client_sock,sizeof(client_sock))))
		{
			if(!(EAGAIN == errno || EWOULDBLOCK == errno))
			{
				log_error("File:%s,Line:%d,Function:%s.read pipe fail.Errno:%d,Info:%s.",
						__FILE__,__LINE__,__FUNCTION__,errno,strerror(errno));
			}
			break;
		}
		else if(0 == bytes)
		{
			log_error("File:%s,Line:%d,Function:%s.read pipe fail.Errno:%d,Info:%s.",
				__FILE__,__LINE__,__FUNCTION__,errno,strerror(errno));
			break;
		}
			
		if(0 < client_sock)
		{
			;//暂时空着，需要判断校验
		}
		task_t *task = taskpool_pop(idx);
		task->sock = client_sock;
		server_work_init(task);

		close(task->sock);
		taskpool_push(task);

	}
}
